/*
  1. 客户端向服务器发送请求，请求登录
    服务器判断用户名和密码是否正确，将用户数据进行jwt（json web token）加密得到token，将token响应给客户端,
  2. 客户端接受到服务器响应，得到token，将token存储起来
  3. 将来客户端发送请求，将token作为请求头参数携带上
    服务器通过解析请求头得到token，对token进行解密得到用户数据，做出相应的响应了
*/
import express from "express";
import jwt from "jsonwebtoken";

const app = express();

const users = [
  {
    id: 1,
    username: "admin",
    password: "111111",
    nickname: "管理员",
  },
];

app.use(express.json()); // 解析 application/json 格式数据
app.use(express.urlencoded({ extended: true })); // 解析 application/x-www-form-urlencoded 格式数据

const secret = "a8q$yPt_A81cw";
// jwt加密得到token
const jwtSign = (data) => {
  return new Promise((resolve) => {
    jwt.sign(
      data,
      secret,
      {
        expiresIn: 10, // 1分钟
      },
      (err, token) => {
        resolve(token);
      }
    );
  });
};
// jwt解密得到加密前的数据
const jwtVerify = (token) => {
  return new Promise((resolve, reject) => {
    jwt.verify(token, secret, function (err, decoded) {
      if (err) {
        reject(err);
      } else {
        resolve(decoded);
      }
    });
  });
};

// 后端路由
// app[请求方式](请求地址, 处理请求的回调函数)
app.post("/login", async (request, response, next) => {
  // 默认请求下，express不解析请求体参数的，需要使用中间件解析才行
  const { username, password } = request.body;

  const user = users.find(
    (user) => user.username === username && user.password === password
  );

  if (user) {
    // 登录成功
    // 对用户数据进行加密，得到token
    const token = await jwtSign(user);

    response.json({
      code: 200,
      data: token,
    });
  } else {
    // 登录失败
    response.json({
      code: 201,
      message: "用户名或密码错误",
    });
  }
});

app.get("/info", async (req, res) => {
  // 默认请求下，express不解析cookie参数的，需要使用中间件解析才行
  const { token } = req.headers;
  try {
    const user = await jwtVerify(token);
    res.json({
      code: 200,
      data: {
        nickname: user.nickname,
      },
    });
  } catch {
    res.status(407).json({
      code: 201,
      message: "token过期",
    });
  }
});

app.listen(3000, (err) => {
  if (err) console.log(err);
  else console.log("服务器启动成功了~");
});
